/**
 * @flow
 * @module query
 * @author zhanpeng.lian
 */

import {
  isFunction,
  isOutLink
} from './validator'

import originMap from 'utils/origin'

/**
 * @method getQuery 通过 key 获取 链接上的 参数
 * @param {String} key  键名
 * @return {queryString}
 */
export function getQuery(key) {
  // 匹配查找包括 search以及hash上带有的所有参数
  // hash参数的权重搞得search参数
  let hash = window.location.hash.replace(/^#(.*\?)?/, '')
  let search = window.location.search.replace(/^\?/, '')
  // 通过key，创建正则表达式，则子表达式 1 则是匹配的最终结果
  let pattern = new RegExp('(?:^|&)' + key + '=(.*?)(?:&|$)')
  let result = pattern.exec(hash + '&' + search)
  return result
    // 匹配的结果进行二次解码，确保输出结果正确性
    ? decodeURIComponent(decodeURIComponent(result[1]))
    : ''
}

/**
 * @method getAllQuery 获取链接上的所有参数
 * @return {queryObject}
 */
export function getAllQuery(type) {
  // 获取并过滤多余的字符
  let hash = window.location.hash.replace(/^#(.*\?)?/, '')
  let search = window.location.search.replace(/^\?/, '')
  let queryString = ''
  switch (type) {
    case 'hash':
      queryString = hash
      break
    case 'search':
      queryString = search
      break
    default:
      queryString = search + '&' + hash
  }
  queryString = queryString.replace(/^&|&$/, '')
  // 子表达式1与子表达式2为键值对
  let pattern = new RegExp('(.*?)=(.*?)(&|$)', 'g')
  let result
  let query = {}
  result = pattern.exec(queryString)
  while (result) {
    query[result[1]] = decodeURIComponent((result[2]))
    result = pattern.exec(queryString)
  }
  return query
}

/**
 * @method encodeQuery 编码query对象为 queryString
 * @param {Object} params query对象
 * @return {queryString} query字符串
 */
export function encodeQuery(params = {}) {
  let paramsData = ''
  Object.keys(params).forEach(function (key) {
    paramsData += key + '=' + encodeURIComponent(params[key]) + '&'
  })
  return paramsData.substring(0, paramsData.length - 1)
}

/**
 * @method decodeQueryObject 解码查询对象参数
 * @param {Object} queryObj 
 */
export function decodeQueryObject(queryObj={}) {
  Object.keys(queryObj).forEach(function (key) {
    queryObj[key] = decodeURIComponent(queryObj[key])
  })

  return queryObj
}

/**
 * 根据路径-域名映射获取链接对应的目标主机
 * @param {*} url 需要跳转的
 */
export default function getTargetOrigin(url) {
  let origin = location.origin
  if (isOutLink(url)) return origin

  let pathKeys = Object.keys(originMap)
  for(let index = 0; index < pathKeys.length; index++) {
    if (url.indexOf(pathKeys[index]) === 0) {
      origin = originMap[pathKeys[index]].target

      if (isFunction(origin)) {
        origin = origin()
      }
      break
    }
  }

  // console.log('origin-->', origin)

  return origin
}

// app内打开新窗口需要完整带上协议名称
export function checkLinkProtocol(link) {
  if (/^(http|https):\/\//.test(link)) {
    return link
  } else {
    return `http://${link}`
  }
}

/**
 * 拼接完整链接，无域名的情况下拼接当前域名
 * @param {*} url 链接
 * @param {*} origin 域名
 */
export function getFullUrl(url) {
  if (isOutLink(url)) {
    return checkLinkProtocol(url)
  } else {
    let origin = getTargetOrigin(url)

    origin = origin.replace(/\/$/, '')
    url = url.replace(/^\//, '')

    return `${origin}/${url}`
  }
}
//删除url某个参数和值
export function delQueStr(url, ref) {
  var str = "";
  if (url.indexOf('?') != -1) {
      str = url.substr(url.indexOf('?') + 1);
  }
  else {
      return url;
  }
  var arr = "";
  var returnurl = "";
  var setparam = "";
  if (str.indexOf('&') != -1) {
      arr = str.split('&');
      for (let i in arr) {
          if (arr[i].split('=')[0] != ref) {
              returnurl = returnurl + arr[i].split('=')[0] + "=" + arr[i].split('=')[1] + "&";
          }
      }
      return url.substr(0, url.indexOf('?')) + "?" + returnurl.substr(0, returnurl.length - 1);
  }
  else {
    arr = str.split('=');
    if (arr[0] == ref) {
        return url.substr(0, url.indexOf('?'));
    }
    else {
        return url;
    }
  }
}


/**
 * @method string2boolean 把路由携带的字符串'true'、'false'转成布尔值
 * @param {String} object 传入对象
 * @return {object} 转换后的对象
 */
export function string2boolean(object) {
  for (let i in object) {
      if (object[i] == 'true') {
          object[i] = true;
      } else if (object[i] == 'false') {
          object[i] = false;
      }
  }
  return object;
}